package com.cmcc.pcap.packet.sctp.sctp.xdr;

import com.cmcc.pcap.packet.sctp.SctpConnection;
import com.cmcc.pcap.packet.sctp.SctpPacketDecorator;
import com.cmcc.pcap.packet.util.PacketAnalysisConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.pcap4j.packet.namednumber.SctpChunkType;

import java.util.ArrayList;

public class SctpStatistics {
    public SctpConnection sctpConnection;

    /**
     * TODO
     * UL Data上行流量
     * DL Data下行流量
     * UL IP Packet上行IP包数
     * DL IP Packet下行IP包数
     * UL_IP_FRAG_PACKETS上行IP包的分片数
     * DL_IP_FRAG_PACKETS下行IP包的分片数
     * SCTP INIT Num：SCTP INIT报文个数
     * SCTP INIT ACK Num：SCTP INIT ACK报文个数
     * SCTP COOKIE ECHO Num：SCTP COOKIE ECHO报文个数
     * SCTP COOKIE ACK Num：SCTP COOKIE ACK报文个数
     * SCTP HEARTBEAT Num：SCTP HEARTBEAT报文个数
     * SCTP HEARTBEAT ACK Num：SCTP HEARTBEAT ACK报文个数
     */
    public static Logger logger = LogManager.getLogger(SctpStatistics.class);

    public int UL_Data=0;
    public int DL_Data=0;//单位为字节
    public int UL_IP_Packet=0;
    public int DL_IP_Packet=0;
    public int UL_Retrans_IP_Packet=0;
    public int DL_Retrans_IP_Packet=0;
    public int UL_Dup_ACK_IP_Packet=0;
    public int DL_Dup_ACK_IP_Packet=0;

    public int SCTP_INIT_Num=0;
    public int SCTP_INIT_ACK_Num=0;
    public int SCTP_COOKIE_ECHO_Num=0;
    public int SCTP_COOKIE_ACK_Num=0;

    public int SCTP_HEARTBEAT=0;
    public int SCTP_HEARTBEAT_ACK=0;

    public int max_DL_Data=0;
    public long timestamp_DL_Data;
    public boolean isOverThreshold=false;
    public ArrayList<SctpPacketDecorator> al_splited;

    public SctpStatistics(SctpConnection sctpConnection) {
        this.sctpConnection = sctpConnection;
        al_splited = sctpConnection.retransmissionDataMergeAl;
        max_DL_Data = PacketAnalysisConfig.getConfigAsInt("sctp.packet.dl.threshold")*1024;//配置文件的单位是KByte，转换成Byte
    }

    public void SctpStat(){

        for(SctpPacketDecorator sctp_packet_decorator:al_splited){
            String src_Addr = String.valueOf(sctp_packet_decorator.ipPacket.getHeader().getSrcAddr())+":"+String.valueOf(sctp_packet_decorator.sctpPacket.getHeader().getSrcPort().valueAsInt());
            String dst_Addr = String.valueOf(sctp_packet_decorator.ipPacket.getHeader().getDstAddr())+":"+String.valueOf(sctp_packet_decorator.sctpPacket.getHeader().getDstPort().valueAsInt());
            if((src_Addr.equals("/"+this.sctpConnection.clientAddr)) && (dst_Addr.equals("/"+this.sctpConnection.serverAddr))){
                UL_IP_Packet++;
                if (sctp_packet_decorator.sctpPacket.getRawData()!=null){
                    UL_Data += sctp_packet_decorator.sctpPacket.getRawData().length;
                }

                if(sctp_packet_decorator.isRetransmissionDataMerge){
                    UL_IP_Packet+=sctp_packet_decorator.retransmissionMergeDataAl.size();
                    this.RetransData_Statistic(sctp_packet_decorator,0);
                }

                if(sctp_packet_decorator.isDuplicateSackMerge){
                    UL_IP_Packet+=sctp_packet_decorator.duplicateSackMergeAl.size();
                    this.DuplicateSack_Statistc(sctp_packet_decorator,0);
                }

            }
            else if((src_Addr.equals("/"+this.sctpConnection.serverAddr))&&(dst_Addr.equals("/"+this.sctpConnection.clientAddr))){
                DL_IP_Packet++;
                if (sctp_packet_decorator.sctpPacket.getRawData()!=null)
                    DL_Data += sctp_packet_decorator.sctpPacket.getRawData().length;
                //判断是否超过下行流量阈值：数据包个数超过阈值/ip包的MTU、下行流量超过阈值、截止到上一个数据包还没超过阈值
                if((DL_IP_Packet>=max_DL_Data/1480)&&(DL_Data>=max_DL_Data)&&(isOverThreshold==false)){
                    isOverThreshold=true;
                    timestamp_DL_Data = sctp_packet_decorator.timestamp.getTime();
                }

                if(sctp_packet_decorator.isRetransmissionDataMerge){
                    DL_IP_Packet+=sctp_packet_decorator.retransmissionMergeDataAl.size();
                    this.RetransData_Statistic(sctp_packet_decorator,1);
                }

                if(sctp_packet_decorator.isDuplicateSackMerge){
                    DL_IP_Packet+=sctp_packet_decorator.duplicateSackMergeAl.size();
                    this.DuplicateSack_Statistc(sctp_packet_decorator,1);
                }

            }
            /*
			四次握手：
			Client --> INIT报文----> Server
			Client <-- INIT_ACK报文 <-- Server
			Client --> COOKIE_ECHO报文 --> Server
            Client <-- COOKIE_ECHO_ACK报文 <--Server
             */
            if (sctp_packet_decorator.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.INIT)){
                SCTP_INIT_Num++;
            }
            else if (sctp_packet_decorator.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.INIT_ACK)){
                SCTP_INIT_ACK_Num++;
            }
            else if (sctp_packet_decorator.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.COOKIE_ECHO)){
                SCTP_COOKIE_ECHO_Num++;
            }
            else if(sctp_packet_decorator.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.COOKIE_ACK)){
                SCTP_COOKIE_ACK_Num++;
            }
            else if(sctp_packet_decorator.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.HEARTBEAT)){
                SCTP_HEARTBEAT++;
            }
            else if(sctp_packet_decorator.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.HEARTBEAT_ACK)){
                SCTP_HEARTBEAT_ACK++;
            }
        }


    }

    //处理重传的数据包，上行数据包direction=0，下行direction=1
    public void RetransData_Statistic (SctpPacketDecorator spd, int direction){
        if (direction==0){
            UL_Retrans_IP_Packet+=spd.retransmissionMergeDataAl.size();//不算重传成功的数据包
            UL_IP_Packet = UL_IP_Packet+spd.retransmissionMergeDataAl.size();
            for(SctpPacketDecorator sctp_packet_retrans:spd.retransmissionMergeDataAl){
                UL_Data += sctp_packet_retrans.sctpPacket.getRawData().length;//上行流量不用和阈值比较，直接累加
            }
        }else{
            DL_Retrans_IP_Packet+=spd.retransmissionMergeDataAl.size();//不算重传成功的数据包
            DL_IP_Packet = DL_IP_Packet+spd.retransmissionMergeDataAl.size();
            for(SctpPacketDecorator sctp_packet_retrans:spd.retransmissionMergeDataAl){
                DL_Data += sctp_packet_retrans.sctpPacket.getRawData().length;//单独记录重传数据包的流量，最后累加。
            }
        }
    }

    public void DuplicateSack_Statistc(SctpPacketDecorator spd, int direction){
        if(direction==0){
            UL_Dup_ACK_IP_Packet+=spd.duplicateSackMergeAl.size();
            UL_IP_Packet = UL_IP_Packet+spd.duplicateSackMergeAl.size();
            for (SctpPacketDecorator sctp_packet_dupack:spd.duplicateSackMergeAl){
                UL_Data += sctp_packet_dupack.sctpPacket.getRawData().length;
            }
        }else{
            DL_Dup_ACK_IP_Packet+=spd.duplicateSackMergeAl.size();
            DL_IP_Packet = DL_IP_Packet+spd.duplicateSackMergeAl.size();
            for(SctpPacketDecorator sctp_packet_dupack:spd.duplicateSackMergeAl){
                DL_Data += sctp_packet_dupack.sctpPacket.getRawData().length;
            }

        }
    }
}
